import re
from typing import Dict, Any, Optional
from urllib.parse import urlparse

# 导入各平台的服务
from service.facebook_downloader_service import FacebookDownloaderService
from service.instagram_downloader_service import InstagramDownloaderService  
from service.twitter_downloader_service import TwitterDownloaderService
from service.youtube_downloader_service import YouTubeDownloaderService

# 导入通用DTO
from dto.universal_response import (
    VideoPlatform, 
    UniversalVideoInfo,
    UniversalVideoDownload,
    UniversalMultiQualityInfo,
    VideoFormat,
    UniversalQualityUrl
)

from config.logging_config import ProjectLoggers

logger = ProjectLoggers.get_service_logger()

class UniversalDownloaderService:
    """通用视频下载服务 - 自动识别平台并调用对应服务"""
    
    def __init__(self):
        # 初始化各平台服务
        self.facebook_service = FacebookDownloaderService()
        self.instagram_service = InstagramDownloaderService()
        self.twitter_service = TwitterDownloaderService()
        self.youtube_service = YouTubeDownloaderService()
        
        # 平台识别规则
        self.platform_patterns = {
            VideoPlatform.FACEBOOK: [
                r'https?://(www\.|m\.)?facebook\.com/(watch|videos|posts|reel)',
                r'https?://(www\.)?fb\.watch/',
            ],
            VideoPlatform.INSTAGRAM: [
                r'https?://(www\.)?instagram\.com/(p|reel|tv)/',
            ],
            VideoPlatform.TWITTER: [
                r'https?://(www\.)?(twitter\.com|x\.com|mobile\.twitter\.com)/.+/status/\d+',
                r'https?://(www\.)?(twitter\.com|x\.com)/i/web/status/\d+',
            ],
            VideoPlatform.YOUTUBE: [
                r'https?://(www\.)?(youtube\.com|youtu\.be)/',
                r'https?://(www\.)?m\.youtube\.com/',
                r'https?://youtube\.com/shorts/',
            ]
        }
    
    def detect_platform(self, url: str) -> VideoPlatform:
        """检测视频链接所属平台"""
        try:
            for platform, patterns in self.platform_patterns.items():
                for pattern in patterns:
                    if re.search(pattern, url):
                        logger.info(f"检测到平台: {platform.value} for URL: {url}")
                        return platform
            
            logger.warning(f"无法识别平台: {url}")
            return VideoPlatform.UNKNOWN
            
        except Exception as e:
            logger.error(f"平台检测失败: {str(e)}")
            return VideoPlatform.UNKNOWN
    
    def _normalize_facebook_data(self, data: Dict[str, Any], data_type: str) -> Dict[str, Any]:
        """标准化Facebook数据格式"""
        if data_type == "info":
            formats = []
            for fmt in data.get("formats", []):
                formats.append(VideoFormat(
                    format_id=fmt.get("format_id"),
                    ext=fmt.get("ext"),
                    resolution=fmt.get("resolution"),
                    width=fmt.get("width"),
                    height=fmt.get("height"),
                    filesize=fmt.get("filesize"),
                    filesize_approx=fmt.get("filesize_approx"),
                    url=fmt.get("url"),
                    quality=fmt.get("quality"),
                    fps=fmt.get("fps"),
                    vcodec=fmt.get("vcodec"),
                    acodec=fmt.get("acodec"),
                    tbr=fmt.get("tbr")
                ).dict())
            
            return UniversalVideoInfo(
                platform=VideoPlatform.FACEBOOK,
                video_id=data.get("video_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                duration=data.get("duration"),
                width=data.get("width"),
                height=data.get("height"),
                thumbnail=data.get("thumbnail"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("share_count"),
                upload_date=data.get("upload_date"),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video"),
                formats=formats
            ).dict()
            
        elif data_type == "download":
            return UniversalVideoDownload(
                platform=VideoPlatform.FACEBOOK,
                video_id=data.get("video_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                download_url=data.get("download_url"),
                format=data.get("format"),
                resolution=data.get("resolution"),
                width=data.get("width"),
                height=data.get("height"),
                filesize=data.get("filesize"),
                filesize_approx=data.get("filesize_approx"),
                duration=data.get("duration"),
                thumbnail=data.get("thumbnail"),
                fps=data.get("fps"),
                vcodec=data.get("vcodec"),
                acodec=data.get("acodec"),
                tbr=data.get("tbr"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("share_count"),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video")
            ).dict()
            
        elif data_type == "multi_quality":
            quality_urls = {}
            for quality, quality_data in data.get("quality_urls", {}).items():
                quality_urls[quality] = UniversalQualityUrl(
                    url=quality_data.get("url"),
                    format=quality_data.get("format"),
                    resolution=quality_data.get("resolution"),
                    width=quality_data.get("width"),
                    height=quality_data.get("height"),
                    filesize=quality_data.get("filesize"),
                    filesize_approx=quality_data.get("filesize_approx"),
                    fps=quality_data.get("fps"),
                    vcodec=quality_data.get("vcodec"),
                    acodec=quality_data.get("acodec"),
                    tbr=quality_data.get("tbr")
                ).dict()
            
            return UniversalMultiQualityInfo(
                platform=VideoPlatform.FACEBOOK,
                video_id=data.get("video_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                duration=data.get("duration"),
                thumbnail=data.get("thumbnail"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("share_count"),
                quality_urls=quality_urls,
                available_qualities=data.get("available_qualities", []),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video")
            ).dict()
        
        return data
    
    def _normalize_instagram_data(self, data: Dict[str, Any], data_type: str) -> Dict[str, Any]:
        """标准化Instagram数据格式"""
        if data_type == "info":
            formats = []
            for fmt in data.get("formats", []):
                formats.append(VideoFormat(
                    format_id=fmt.get("format_id"),
                    ext=fmt.get("ext"),
                    resolution=fmt.get("resolution"),
                    width=fmt.get("width"),
                    height=fmt.get("height"),
                    filesize=fmt.get("filesize"),
                    filesize_approx=fmt.get("filesize_approx"),
                    url=fmt.get("url"),
                    quality=fmt.get("quality"),
                    fps=fmt.get("fps"),
                    vcodec=fmt.get("vcodec"),
                    acodec=fmt.get("acodec"),
                    tbr=fmt.get("tbr")
                ).dict())
            
            return UniversalVideoInfo(
                platform=VideoPlatform.INSTAGRAM,
                video_id=data.get("media_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                duration=data.get("duration"),
                width=data.get("width"),
                height=data.get("height"),
                thumbnail=data.get("thumbnail"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("share_count"),  # Instagram可能没有这个字段
                upload_date=data.get("upload_date"),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video"),
                formats=formats
            ).dict()
            
        elif data_type == "download":
            return UniversalVideoDownload(
                platform=VideoPlatform.INSTAGRAM,
                video_id=data.get("media_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                download_url=data.get("download_url"),
                format=data.get("format"),
                resolution=data.get("resolution"),
                width=data.get("width"),
                height=data.get("height"),
                filesize=data.get("filesize"),
                filesize_approx=data.get("filesize_approx"),
                duration=data.get("duration"),
                thumbnail=data.get("thumbnail"),
                fps=data.get("fps"),
                vcodec=data.get("vcodec"),
                acodec=data.get("acodec"),
                tbr=data.get("tbr"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("share_count"),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video")
            ).dict()
            
        elif data_type == "multi_quality":
            quality_urls = {}
            for quality, quality_data in data.get("quality_urls", {}).items():
                quality_urls[quality] = UniversalQualityUrl(
                    url=quality_data.get("url"),
                    format=quality_data.get("format"),
                    resolution=quality_data.get("resolution"),
                    width=quality_data.get("width"),
                    height=quality_data.get("height"),
                    filesize=quality_data.get("filesize"),
                    filesize_approx=quality_data.get("filesize_approx"),
                    fps=quality_data.get("fps"),
                    vcodec=quality_data.get("vcodec"),
                    acodec=quality_data.get("acodec"),
                    tbr=quality_data.get("tbr")
                ).dict()
            
            return UniversalMultiQualityInfo(
                platform=VideoPlatform.INSTAGRAM,
                video_id=data.get("media_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                duration=data.get("duration"),
                thumbnail=data.get("thumbnail"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("share_count"),
                quality_urls=quality_urls,
                available_qualities=data.get("available_qualities", []),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video")
            ).dict()
        
        return data
    
    def _normalize_twitter_data(self, data: Dict[str, Any], data_type: str) -> Dict[str, Any]:
        """标准化Twitter数据格式"""
        if data_type == "info":
            formats = []
            for fmt in data.get("formats", []):
                formats.append(VideoFormat(
                    format_id=fmt.get("format_id"),
                    ext=fmt.get("ext"),
                    resolution=fmt.get("resolution"),
                    width=fmt.get("width"),
                    height=fmt.get("height"),
                    filesize=fmt.get("filesize"),
                    filesize_approx=fmt.get("filesize_approx"),
                    url=fmt.get("url"),
                    quality=fmt.get("quality"),
                    fps=fmt.get("fps"),
                    vcodec=fmt.get("vcodec"),
                    acodec=fmt.get("acodec"),
                    tbr=fmt.get("tbr")
                ).dict())
            
            return UniversalVideoInfo(
                platform=VideoPlatform.TWITTER,
                video_id=data.get("tweet_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                duration=data.get("duration"),
                width=data.get("width"),
                height=data.get("height"),
                thumbnail=data.get("thumbnail"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("repost_count"),  # Twitter用repost_count
                upload_date=data.get("upload_date"),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video"),
                formats=formats
            ).dict()
            
        elif data_type == "download":
            return UniversalVideoDownload(
                platform=VideoPlatform.TWITTER,
                video_id=data.get("tweet_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                download_url=data.get("download_url"),
                format=data.get("format"),
                resolution=data.get("resolution"),
                width=data.get("width"),
                height=data.get("height"),
                filesize=data.get("filesize"),
                filesize_approx=data.get("filesize_approx"),
                duration=data.get("duration"),
                thumbnail=data.get("thumbnail"),
                fps=data.get("fps"),
                vcodec=data.get("vcodec"),
                acodec=data.get("acodec"),
                tbr=data.get("tbr"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("repost_count"),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video")
            ).dict()
            
        elif data_type == "multi_quality":
            quality_urls = {}
            for quality, quality_data in data.get("quality_urls", {}).items():
                quality_urls[quality] = UniversalQualityUrl(
                    url=quality_data.get("url"),
                    format=quality_data.get("format"),
                    resolution=quality_data.get("resolution"),
                    width=quality_data.get("width"),
                    height=quality_data.get("height"),
                    filesize=quality_data.get("filesize"),
                    filesize_approx=quality_data.get("filesize_approx"),
                    fps=quality_data.get("fps"),
                    vcodec=quality_data.get("vcodec"),
                    acodec=quality_data.get("acodec"),
                    tbr=quality_data.get("tbr")
                ).dict()
            
            return UniversalMultiQualityInfo(
                platform=VideoPlatform.TWITTER,
                video_id=data.get("tweet_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                duration=data.get("duration"),
                thumbnail=data.get("thumbnail"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("repost_count"),
                quality_urls=quality_urls,
                available_qualities=data.get("available_qualities", []),
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video")
            ).dict()
        
        return data
    
    def _normalize_youtube_data(self, data: Dict[str, Any], data_type: str) -> Dict[str, Any]:
        """标准化YouTube数据格式"""
        if data_type == "download":
            return UniversalVideoDownload(
                platform=VideoPlatform.YOUTUBE,
                video_id=data.get("video_id"),
                title=data.get("title"),
                description=data.get("description"),
                uploader=data.get("uploader"),
                uploader_id=data.get("uploader_id"),
                uploader_url=data.get("uploader_url"),
                download_url=data.get("download_url"),
                format=data.get("format"),
                resolution=data.get("resolution"),
                width=data.get("width"),
                height=data.get("height"),
                filesize=data.get("filesize"),
                filesize_approx=data.get("filesize_approx"),
                duration=data.get("duration"),
                thumbnail=data.get("thumbnail"),
                fps=data.get("fps"),
                vcodec=data.get("vcodec"),
                acodec=data.get("acodec"),
                tbr=data.get("tbr"),
                view_count=data.get("view_count"),
                like_count=data.get("like_count"),
                comment_count=data.get("comment_count"),
                share_count=data.get("share_count"),  # YouTube可能没有分享数
                timestamp=data.get("timestamp"),
                webpage_url=data.get("webpage_url"),
                is_video=data.get("is_video")
            ).dict()
        
        return data
    
    async def get_video_info(self, url: str) -> Dict[str, Any]:
        """获取视频信息 - 自动识别平台"""
        try:
            platform = self.detect_platform(url)
            
            if platform == VideoPlatform.UNKNOWN:
                return {
                    "success": False,
                    "platform": platform,
                    "error": "不支持的视频平台"
                }
            
            # 根据平台调用对应服务
            if platform == VideoPlatform.FACEBOOK:
                result = await self.facebook_service.get_video_info(url)
                if result["success"]:
                    result["data"] = self._normalize_facebook_data(result["data"], "info")
                    
            elif platform == VideoPlatform.INSTAGRAM:
                result = await self.instagram_service.get_media_info(url)
                if result["success"]:
                    result["data"] = self._normalize_instagram_data(result["data"], "info")
                    
            elif platform == VideoPlatform.TWITTER:
                result = await self.twitter_service.get_tweet_info(url)
                if result["success"]:
                    result["data"] = self._normalize_twitter_data(result["data"], "info")
            
            # 添加平台信息到结果中
            result["platform"] = platform
            
            logger.info(f"获取视频信息成功: {platform.value} - {url}")
            return result
            
        except Exception as e:
            logger.error(f"获取视频信息失败: {str(e)}")
            return {
                "success": False,
                "platform": VideoPlatform.UNKNOWN,
                "error": f"获取视频信息失败: {str(e)}"
            }
    
    async def get_download_url(self, url: str, quality: str = "best") -> Dict[str, Any]:
        """获取下载链接 - 自动识别平台"""
        try:
            platform = self.detect_platform(url)
            
            if platform == VideoPlatform.UNKNOWN:
                return {
                    "success": False,
                    "platform": platform,
                    "error": "不支持的视频平台"
                }
            
            # 根据平台调用对应服务
            if platform == VideoPlatform.FACEBOOK:
                result = await self.facebook_service.get_download_urls(url, quality)
                if result["success"]:
                    result["data"] = self._normalize_facebook_data(result["data"], "download")
                    
            elif platform == VideoPlatform.INSTAGRAM:
                result = await self.instagram_service.get_download_urls(url, quality)
                if result["success"]:
                    result["data"] = self._normalize_instagram_data(result["data"], "download")
                    
            elif platform == VideoPlatform.TWITTER:
                result = await self.twitter_service.get_download_urls(url, quality)
                if result["success"]:
                    result["data"] = self._normalize_twitter_data(result["data"], "download")
                    
            elif platform == VideoPlatform.YOUTUBE:
                result = await self.youtube_service.get_download_urls_with_audio_fallback(url, quality)
                if result["success"]:
                    result["data"] = self._normalize_youtube_data(result["data"], "download")
            
            # 添加平台信息到结果中
            result["platform"] = platform
            
            logger.info(f"获取下载链接成功: {platform.value} - {url}")
            return result
            
        except Exception as e:
            logger.error(f"获取下载链接失败: {str(e)}")
            return {
                "success": False,
                "platform": VideoPlatform.UNKNOWN,
                "error": f"获取下载链接失败: {str(e)}"
            }
    
    async def get_multiple_quality_urls(self, url: str) -> Dict[str, Any]:
        """获取多质量下载链接 - 自动识别平台"""
        try:
            platform = self.detect_platform(url)
            
            if platform == VideoPlatform.UNKNOWN:
                return {
                    "success": False,
                    "platform": platform,
                    "error": "不支持的视频平台"
                }
            
            # 根据平台调用对应服务
            if platform == VideoPlatform.FACEBOOK:
                result = await self.facebook_service.get_multiple_quality_urls(url)
                if result["success"]:
                    result["data"] = self._normalize_facebook_data(result["data"], "multi_quality")
                    
            elif platform == VideoPlatform.INSTAGRAM:
                result = await self.instagram_service.get_multiple_quality_urls(url)
                if result["success"]:
                    result["data"] = self._normalize_instagram_data(result["data"], "multi_quality")
                    
            elif platform == VideoPlatform.TWITTER:
                result = await self.twitter_service.get_multiple_quality_urls(url)
                if result["success"]:
                    result["data"] = self._normalize_twitter_data(result["data"], "multi_quality")
            
            # 添加平台信息到结果中
            result["platform"] = platform
            
            logger.info(f"获取多质量下载链接成功: {platform.value} - {url}")
            return result
            
        except Exception as e:
            logger.error(f"获取多质量下载链接失败: {str(e)}")
            return {
                "success": False,
                "platform": VideoPlatform.UNKNOWN,
                "error": f"获取多质量下载链接失败: {str(e)}"
            } 